package edu.drexel.info636.assignments.controllers;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import edu.drexel.info636.assignments.models.Record;
import edu.drexel.info636.assignments.models.RecordList;

/**
 * Handles a particular record set (set of numbers) events.
 * 
 * @author Chase Miller
 * 
 */
@Component
public class RecordListController extends ControllerBase {

    @Autowired
    private FileController fileController;

    @Autowired
    private RecordController recordItemController;

    private RecordList recordList;

    /**
     * Creates a new instance of this object.
     */
    public RecordListController() {
	this.recordList = new RecordList();
    }

    /**
     * Reads the system's records.
     * 
     * @return - The Record.
     */
    public RecordList readRecords() {
	this.fileController.ensureExistingFile();

	try {
	    BufferedReader br = new BufferedReader(new FileReader(this.fileController.getFilePath()));

	    this.recordList = new RecordList(br);

	    br.close();

	} catch (IOException e) {
	}

	return this.recordList;
    }

    /**
     * Populates the record list by interacting with the user.
     */
    public void populateRecordList() {
	// Get the quantity. Keep prompting until a valid quantity is provided.
	int quantity = 0;
	while (quantity <= 0) {
	    System.out.println("Please enter the quantity of records (sets of numbers) to be recorded");

	    try {
		quantity = Integer.parseInt(this.scan.nextLine());
	    } catch (Throwable t) {
	    }
	}

	for (int i = 0; i < quantity; i++) {
	    System.out.println(System.lineSeparator() + "Entering record " + (i + 1) + " of " + quantity);

	    Record newRecord = this.recordItemController.getRecordItemFromUser();

	    this.recordList.getItems().add(newRecord);
	}
    }

    /**
     * Writes the record.
     * 
     * @param silentlyOverwrite
     *            - If true, this will silently overwrite any existing record.
     *            Otherwise, it won't.
     */
    public void writeRecords(boolean silentlyOverwrite) {
	if (!silentlyOverwrite) {
	    this.fileController.ensureNewFile();
	}

	System.out.println("Writing records");

	try {
	    PrintWriter writer = new PrintWriter(this.fileController.getFilePath(), "UTF-8");

	    this.recordList.write(writer);

	    writer.close();

	    System.out.println("Write complete");
	} catch (FileNotFoundException ex) {
	    System.out.println("The file could not be found - " + this.fileController.getFilePath());
	    System.exit(0);
	} catch (UnsupportedEncodingException ex) {
	    System.out.println("The encoding type was not correct.  Contact the developer.");
	}
    }

    /**
     * Prints the numbers in the list.
     */
    public void printRecordList() {
	System.out.println("Record listing:");

	System.out.println(this.recordList);
    }

    /**
     * Prompts the user to modify existing records.
     */
    public void modifyRecordList() {
	this.readRecords();

	/* A little bit of variable setup. */
	RecordList newList = new RecordList();

	/* Print all the records in a summary fashion. */
	this.printRecordList();

	/* Go through each record and prompt for actions */
	System.out.println("\n\nStarting record-by-record modification...\n");

	Boolean acceptRemainder = false;

	for (Record nextRecordItem : this.recordList.getItems()) {
	    if (acceptRemainder) {
		newList.getItems().add(nextRecordItem);
	    } else {

		Record modifiedRecord = this.recordItemController.modifyRecordItem(nextRecordItem);

		newList.getItems().add(modifiedRecord);

		/* Insert a new record? */
		Boolean insertNewNumber = this.genericBooleanPromptAndResponse("Would you like to insert a new record after this record (y/n)?");
		if (insertNewNumber == true) {
		    newList.getItems().add(this.recordItemController.getRecordItemFromUser());
		}

		/* Accept the remaining records? */
		acceptRemainder = this.acceptRemainder();

		System.out.println("\n");
	    }
	}

	System.out.println("All records have been modified.\n\n");

	this.recordList = newList;

	/*
	 * Prompt the user whether to save a new file or modify the existing and
	 * do so.
	 */
	if (getSaveToNewFileDecision()) {
	    this.fileController.getFilePathFromUser();
	    this.writeRecords(false);
	} else {
	    this.writeRecords(true);
	}
    }

    /**
     * Prompts the user whether the rest of the numbers should be accepted.
     * 
     * @return - True or false.
     */
    private Boolean acceptRemainder() {

	return this.genericBooleanPromptAndResponse("Would you like to accept the remaining records? (y/n)");
    }

    /**
     * Prompts the user whether to save to a new file or modify the existing
     * file.
     * 
     * @return - True if we should save to a new file.
     */
    private Boolean getSaveToNewFileDecision() {
	return this.genericBooleanPromptAndResponse("Would you like to save to a new file (y)?  If (n), existing file will be modified.");
    }
}
